package com.client.view;

import com.client.bean.UserInfo;
import com.client.common.CmdControl;
import com.client.common.SendMsg;
import com.client.common.SendServer;
import com.client.common.Sound;
import com.client.db.UserDbOper;


import javax.swing.*;
import javax.swing.event.ListDataListener;
import java.awt.*;
import java.awt.event.*;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Hashtable;
import java.util.TimerTask;
import java.util.Vector;

/**
 * Created by Administrator on 2016/12/17.
 */
public class MainView extends JFrame implements MouseListener ,ActionListener , WindowListener ,ItemListener{
	public UserInfo userInfo ,friendUserInfo;
	private JTabbedPane tab;
	public JLabel lblhead;
	private JList lstFriend, lstFamily, lstclassmate, lsthmd;
	private JButton btnFind;
	private Vector<UserInfo> vFriend, vFamily, vClassmate, vHmd, vAllDetail;

	private JMenu menu;
	private JMenuItem miChat , miLookInfo ,miDel ,miFriend , miFamily , miClassmate , miHmd;
	private Hashtable<Integer , ChatView> Chat_OnLineUsers = null;
	private JComboBox cbStatus;

	private JPopupMenu pop;
	/**
	 * 托盘菜单
	 */
	private PopupMenu popicon;
	private MenuItem miexit , miopen;
	TrayIcon trayIcon;//托盘图标

	public MainView() throws HeadlessException {

	}

	public MainView(UserInfo userInfo) {
		this.userInfo = userInfo;

		setTitle(userInfo.getNicknName());
		setIconImage(new ImageIcon(userInfo.getFace()).getImage());
		//获取昵称，备注，qq号码，个性签名
		String str = "";
		if (userInfo.getRemark() != null && !userInfo.getRemark().equals("")) {
			str = userInfo.getRemark() + "(";
		} else {
			str = userInfo.getNicknName() + "(";
		}
		str += userInfo.getCode() + ")," + userInfo.getInformation();
		lblhead = new JLabel(str, new ImageIcon(userInfo.getFace()), JLabel.LEFT);
		lblhead.addMouseListener(this);
		add(lblhead, BorderLayout.NORTH);

		/**
		 * 状态设置
		 */
		String[] status = {"在线" , "忙碌" , "隐身"};
		cbStatus = new JComboBox(status);

		vFriend = new Vector<UserInfo>();
		vFamily = new Vector<UserInfo>();
		vClassmate = new Vector<UserInfo>();
		vHmd = new Vector<UserInfo>();

		lstFamily = new JList();
		lstFriend = new JList();
		lstclassmate = new JList();
		lsthmd = new JList();

		lstFriend.addMouseListener(this);
		lstFamily.addMouseListener(this);
		lstclassmate.addMouseListener(this);
		lsthmd.addMouseListener(this);
		addWindowListener(this);


		refresh();
		tab = new JTabbedPane();
		tab.addTab("好友", new JScrollPane(lstFriend));
		tab.addTab("家人", new JScrollPane(lstFamily));
		tab.addTab("同学", new JScrollPane(lstclassmate));
		tab.addTab("黑名单", new JScrollPane(lsthmd));
		add(tab, BorderLayout.CENTER);
		createMenu();
		btnFind = new JButton("查找好友");
		btnFind.addActionListener(this);
		JPanel southPanel = new JPanel(new GridLayout(2,1,10,0));
		southPanel.add(btnFind);
		southPanel.add(cbStatus);
		cbStatus.addItemListener(this);
		add(southPanel, BorderLayout.SOUTH);
//		add(btnFind, BorderLayout.SOUTH);

		createPopupMenu();//创建托盘菜单
		setTrayIcon();//创建托盘图标
		trayIcon.addMouseListener(this);

		setSize(250, 670);
		setVisible(true);
		setResizable(false);

		int width = Toolkit.getDefaultToolkit().getScreenSize().width - 400;
		setLocation(width, 50);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		new ReceThread().start();

		call(CmdControl.CMD_ONLINE);//上线通知

	}

	/**
	 * 设置托盘菜单图标
	 */
	public void setTrayIcon() {
		Image image = new ImageIcon(userInfo.getFace()).getImage();
		trayIcon = new TrayIcon(image , "快聊" , popicon);
		trayIcon.setImageAutoSize(true);//自动调整图标的大小
	}

	/**
	 * 创建托盘菜单
	 */
	public void createPopupMenu() {
		popicon = new PopupMenu();
		miexit = new MenuItem("exit");
		miopen = new MenuItem("open");
		popicon.add(miopen);
		popicon.add(miexit);
		miexit.addActionListener(this);
		miopen.addActionListener(this);
	}

	public static void main(String[] args) {
		new MainView(new UserInfo());
	}

	@Override
	public void mouseClicked(MouseEvent e) {
//		int index = ((JList)e.getSource()).locationToIndex(e.getPoint());
		if (e.getSource() == lstFriend) {
			int index = lstFriend.locationToIndex(e.getPoint());
			lstFriend.setSelectedIndex(index);
			friendUserInfo = vFriend.get(index);

			//双击
			if (e.getClickCount() == 2) {
//				new ChatView(userInfo , friendUserInfo);
				findView(friendUserInfo.getCode() , null);
			}
			//右键
			if (e.getButton() == 3) {
				if (lstFriend.getSelectedIndex() >= 0) {
					pop.show(lstFriend , e.getX() ,e.getY());
				}

			}
		} else if (e.getSource() == lstFamily) {
			int index = lstFamily.locationToIndex(e.getPoint());
			lstFamily.setSelectedIndex(index);
			friendUserInfo = vFamily.get(lstFamily.getSelectedIndex());
			if (e.getClickCount() == 2) {
				findView(friendUserInfo.getCode() , null);
			}
			//右键
			if (e.getButton() == 3) {
				if (lstFamily.getSelectedIndex() >= 0) {
					pop.show(lstFamily , e.getX() ,e.getY());
				}

			}
		} else if (e.getSource() == lstclassmate) {
			int index = lstclassmate.locationToIndex(e.getPoint());
			lstclassmate.setSelectedIndex(index);
			friendUserInfo = vClassmate.get(lstclassmate.getSelectedIndex());
			if (e.getClickCount() == 2) {
				findView(friendUserInfo.getCode() , null);
			}
			//右键
			if (e.getButton() == 3) {
				if (lstclassmate.getSelectedIndex() >= 0) {
					pop.show(lstclassmate , e.getX() ,e.getY());
				}

			}
		} else if (e.getSource() == lsthmd) {
			int index = lsthmd.locationToIndex(e.getPoint());
			lsthmd.setSelectedIndex(index);
			friendUserInfo = vHmd.get(lsthmd.getSelectedIndex());
			if (e.getClickCount() == 2) {
				findView(friendUserInfo.getCode() , null);
			}
			//右键
			if (e.getButton() == 3) {
				if (lsthmd.getSelectedIndex() >= 0) {
					pop.show(lsthmd , e.getX() ,e.getY());
				}
			}
		} else if (e.getSource() == lblhead) {
			if (e.getClickCount() == 2) {
				new RegUser(userInfo , this);
			}
		}
	}

	@Override
	public void mousePressed(MouseEvent e) {

	}

	@Override
	public void mouseReleased(MouseEvent e) {

	}

	@Override
	public void mouseEntered(MouseEvent e) {

	}

	@Override
	public void mouseExited(MouseEvent e) {

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == btnFind) {//查找好友
			new FindView(userInfo);
		} else if (e.getSource() == miChat) {//聊天
//			new ChatView(userInfo , friendUserInfo);
			findView(friendUserInfo.getCode() , null);
		} else if (e.getSource() == miLookInfo) {
			if (friendUserInfo != null) {
				new LookUser(friendUserInfo);
			}

		} else if (e.getSource() == miDel) {
			new UserDbOper().delFriend(userInfo , friendUserInfo.getCode());
			refresh();
		} else if (e.getSource() == miFriend) {
			new UserDbOper().movFriend(userInfo , friendUserInfo.getCode() , CmdControl.F_FRIEND);
			refresh();
		} else if (e.getSource() == miFamily) {
			new UserDbOper().movFriend(userInfo , friendUserInfo.getCode() , CmdControl.F_FAMILY);
			refresh();
		} else if (e.getSource() == miClassmate) {
			new UserDbOper().movFriend(userInfo , friendUserInfo.getCode() , CmdControl.F_CLASSMATE);
			refresh();
		} else if (e.getSource() == miHmd) {
			new UserDbOper().movFriend(userInfo , friendUserInfo.getCode() , CmdControl.F_HMD);
			refresh();
		} else if (e.getSource() == miopen) {
			SystemTray tray = SystemTray.getSystemTray();
			tray.remove(trayIcon);
			MainView.this.setVisible(true);
			MainView.this.setState(JFrame.NORMAL);
		} else if (e.getSource() == miexit) {
			System.exit(0);
		}
	}

	@Override
	public void windowOpened(WindowEvent e) {

	}

	@Override
	public void windowClosing(WindowEvent e) {
		System.out.println("窗口关闭中");
		new UserDbOper().modifyStatus(userInfo.getCode() , CmdControl.F_OFFLINE);
		//发送离线通知
		call(CmdControl.CMD_OFFLINE);
	}

	@Override
	public void windowClosed(WindowEvent e) {

	}

	@Override
	public void windowIconified(WindowEvent e) {
		//获取系统托盘
		SystemTray tray = SystemTray.getSystemTray();

		//创建一个托盘图标
		try {
			if (trayIcon != null) {
				tray.remove(trayIcon);
			}
			tray.add(trayIcon);
			MainView.this.setVisible(false);
		} catch (AWTException ex) {
			System.out.println("无法创建托盘" + ex.getMessage());
		}
	}

	@Override
	public void windowDeiconified(WindowEvent e) {

	}

	@Override
	public void windowActivated(WindowEvent e) {

	}

	@Override
	public void windowDeactivated(WindowEvent e) {

	}

	/**
	 * 在线状态监听
	 * @param e
	 */
	@Override
	public void itemStateChanged(ItemEvent e) {
//		int status;
		int status = cbStatus.getSelectedIndex() + 1 ;
		new UserDbOper().modifyStatus(userInfo.getCode() , status);

		String filename = userInfo.getFace();
		String file = "";
		switch (status){
			case CmdControl.F_OFFLINE:
				file = filename.substring(0, filename.indexOf(".")) + "_h.png";
				call(CmdControl.CMD_OFFLINE);
				break;
			case CmdControl.F_ONLINE:
				file = filename;
				call(CmdControl.CMD_ONLINE);
				break;
			case CmdControl.F_BUSY:
				file = filename.substring(0, filename.indexOf(".")) + "_w.png";
				call(CmdControl.CMD_BUSY);
				break;
			case CmdControl.F_LEVEL://离开
				file = filename.substring(0, filename.indexOf(".")) + "_l.png";
				call(CmdControl.CMD_LEAVE);
				break;
		}
		lblhead.setIcon(new ImageIcon(file));


	}


	class listmodel extends AbstractListModel {

		Vector dats;

		public listmodel(Vector dats) {
			this.dats = dats;
		}

		@Override
		public int getSize() {
			return dats.size();
		}

		@Override
		public Object getElementAt(int index) {
			UserInfo userInfo = (UserInfo) dats.get(index);
			return userInfo.getNicknName().trim() + "[" + userInfo.getCode() + "]";
		}
	}

	class myfind extends DefaultListCellRenderer {
		Vector datas;

		public myfind(Vector datas) {
			this.datas = datas;
		}

		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
			Component c = super.getListCellRendererComponent(list, value,
					index, isSelected, cellHasFocus);
			if (index >= 0 && index < datas.size()) {
				UserInfo userInfo = (UserInfo) datas.get(index);
				//给列表中好友状态设置头像

				String filename = "";
				String file = "";
				switch (userInfo.getStatus()) {
					case CmdControl.F_OFFLINE:
						/**
						 * filename.substring(0, filename.indexOf("."))的得到文件名1.png
						 * substring求子串，第一个参数表示开始位置
						 * indexof指定字符在字符串中的位置
						 */
						filename = userInfo.getFace();
						file = filename.substring(0, filename.indexOf(".")) + "_h.png";
						setIcon(new ImageIcon(file));
						break;
					case CmdControl.F_ONLINE:
						setIcon(new ImageIcon(userInfo.getFace()));
						break;
					case CmdControl.F_BUSY:
						filename = userInfo.getFace();
						file = filename.substring(0, filename.indexOf(".")) + "_w.png";
						setIcon(new ImageIcon(file));
						break;
					case CmdControl.F_LEVEL:
						filename = userInfo.getFace();
						file = filename.substring(0, filename.indexOf(".")) + "_l.png";
						setIcon(new ImageIcon(file));
						break;
				}
//				if (userInfo.getStatus() == 1) {
//					setIcon(new ImageIcon(userInfo.getFace()));
//				} else {
//					String filename = userInfo.getFace();
//					String file = filename.substring(0, filename.indexOf(".")) + "_h.png";
//					setIcon(new ImageIcon(file));
//				}
				setText(userInfo.getNicknName().trim() + "(" + userInfo.getCode() + ")");
			}

			if (isSelected) {
				setBackground(list.getSelectionBackground());
				setForeground(list.getSelectionForeground());
			} else {
				setBackground(list.getBackground());
				setForeground(list.getForeground());
			}
			setEnabled(list.isEnabled());
			setFont(list.getFont());
			setOpaque(true);
			return this;
		}

	}

	//刷新界面
	public void refresh(){
		vAllDetail = new UserDbOper().getAllInfo(userInfo);
		//清除记录
		vFriend.clear();
		vFamily.clear();
		vClassmate.clear();
		vHmd.clear();
		for (int i = 0; i < vAllDetail.size(); i++) {
			UserInfo u = vAllDetail.get(i);
			if (u.getGroupname().equals(CmdControl.F_FRIEND)) {
				vFriend.add(u);
			} else if (u.getGroupname().equals(CmdControl.F_FAMILY)) {
				vFamily.add(u);
			} else if (u.getGroupname().equals(CmdControl.F_CLASSMATE)) {
				vClassmate.add(u);
			} else if (u.getGroupname().equals(CmdControl.F_HMD)) {
				vHmd.add(u);
			}
		}
		//把向量放到list控件
		lstFriend.setModel(new listmodel(vFriend));//显示资料
		lstFriend.setCellRenderer(new myfind(vFriend));//显示头像

		lstFamily.setModel(new listmodel(vFamily));//显示资料
		lstFamily.setCellRenderer(new myfind(vFamily));//显示头像

		lstclassmate.setModel(new listmodel(vClassmate));//显示资料
		lstclassmate.setCellRenderer(new myfind(vClassmate));//显示头像

		lsthmd.setModel(new listmodel(vHmd));//显示资料
		lsthmd.setCellRenderer(new myfind(vHmd));//显示头像

	}

	//创建菜单
	public void createMenu() {
		pop = new JPopupMenu();
		miChat = new JMenuItem("聊天");
		miLookInfo = new JMenuItem("查看资料");
		miFriend = new JMenuItem("移动到好友");
		miFamily = new JMenuItem("移动到家人");
		miClassmate = new JMenuItem("移动到同学");
		miHmd = new JMenuItem("移动到黑名单");
		miDel = new JMenuItem("删除好友");

		miChat.addActionListener(this);
		miLookInfo.addActionListener(this);
		miFriend.addActionListener(this);
		miFamily.addActionListener(this);
		miClassmate.addActionListener(this);
		miHmd.addActionListener(this);
		miDel.addActionListener(this);

		pop.add(miChat);
		pop.add(miLookInfo);
		pop.add(miFriend);
		pop.add(miFamily);
		pop.add(miClassmate);
		pop.add(miHmd);
		pop.add(miDel);
	}

	//查找聊天窗口是否存在，如果不存在则创建，存在则直接显示信息在界面
	public ChatView findView(Integer code ,SendMsg sendMsg) {
		ChatView chatView = null;
		//查找窗口是否存在
		chatView = Chat_OnLineUsers.get(code);

		if (chatView == null) {//不存在则创建
			if (sendMsg == null) {//双击或右键打开窗口
				chatView = new ChatView(userInfo, friendUserInfo);
			} else { //线程打开窗口
				chatView = new ChatView(sendMsg.friendUserInfo, sendMsg.selfUserInfo);
			}
			//把窗口保存到hashtable中
			Chat_OnLineUsers.put(code ,chatView);
		}
		if (!chatView.isVisible()) {
			chatView.show();
		}
		return chatView;
	}

	//上线，离线通知
	public void call (int cmd) {
		if (vAllDetail == null)
			return;
		for (int i = 0; i < vAllDetail.size(); i++) {
			UserInfo u = vAllDetail.get(i);
			//不发给自己，并且朋友必须在线（在线 ，忙碌 ，隐身）
			if (u.getCode() != userInfo.getCode() && u.getStatus() != CmdControl.F_OFFLINE) {
				SendMsg msg = new SendMsg();
				msg.Cmd = cmd;
				msg.selfUserInfo = userInfo;
				msg.friendUserInfo = u;

				//发送
				new SendServer().send(msg);
			}
		}
	}

	/**
	 * 接受线程的线程类
	 */
	class  ReceThread extends Thread {

		public ReceThread() {
			Chat_OnLineUsers = new Hashtable<Integer , ChatView>();
		}

		public void run() {
			try {


				/**
				 * 在此端口接收数据
				 */
				DatagramSocket serverSocket = new DatagramSocket(userInfo.getPort());


				while (true) {
					byte b[] = new byte[1024 * 70];
					DatagramPacket packet = new DatagramPacket(b, b.length);
					serverSocket.receive(packet);

					ByteArrayInputStream bis = new ByteArrayInputStream(b, 0, packet.getLength());

					ObjectInputStream ois = new ObjectInputStream(bis);

					SendMsg msg = (SendMsg) ois.readObject();

					System.out.println("命令字=" + msg.Cmd);

					ChatView chatView = null;

					switch (msg.Cmd) {

						case CmdControl.CMD_ONLINE://登录
							refresh();//更新界面
							new Sound();
							//上线提示
							new TipView(msg.selfUserInfo);
							break;
						case CmdControl.CMD_OFFLINE://下线
						case CmdControl.CMD_LEAVE://离开
						case CmdControl.CMD_BUSY://忙碌
							refresh();
							break;
						case CmdControl.CMD_CHAT://接收聊天消息
//							ChatView chatView = findView(msg.selfUserInfo.getCode() , msg);
							chatView = findView(msg.selfUserInfo.getCode() , msg);
							/**
							 * 获取聊天消息
							 * 并显示到聊天窗口
							 */
							chatView.appendView(msg.selfUserInfo.getNicknName(), msg.doc);

							break;
						case CmdControl.CMD_DOUDONG://接收抖动
							chatView = findView(msg.selfUserInfo.getCode() , msg);
							chatView.shake();
							break;
						case CmdControl.CMD_ADDFRIEND://添加好友
							SendMsg m = new SendMsg();
							m.friendUserInfo = msg.selfUserInfo;
							m.selfUserInfo = msg.friendUserInfo;
							String str = msg.selfUserInfo.getNicknName() + "添加了你为好友,请确认!";
							//如果点击确定按钮就添加
							if (JOptionPane.showConfirmDialog(null , str , "好友申请" , JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
								new UserDbOper().addFriend(msg.friendUserInfo , msg.selfUserInfo.getCode());
								//刷新界面
								refresh();
								m.Cmd = CmdControl.CMD_AGREEFRIEND;
							} else {
								m.Cmd = CmdControl.CMD_REJECTFRIEND;
							}
							new SendServer().send(m);
							break;

						case CmdControl.CMD_AGREEFRIEND://同意添加好友
							refresh();
							break;
						case CmdControl.CMD_REJECTFRIEND://拒绝添加好友
							JOptionPane.showMessageDialog(null , msg.selfUserInfo.getNicknName() + "说:你是个好人");
							break;
					}
				}

				} catch(Exception e){
					e.printStackTrace();
				}
		}

	}



}

